import 'package:mybase/base/tool/db/MyBatch.dart';
import 'package:mybase/base/tool/globalMethod/FFSafeValue.dart';
import 'package:sqflite/sqflite.dart';

/**
 * 抽象类，不用动
 */
abstract class FFsql {
  // 表名
  String getTableName();

  // 主键名
  String getPrimaryKeyName();

  // 创建时间
  String getCreateTime();

  // 更新时间
  String getUpdateTime();

  // 创表语名
  String setCreateSql(
    String tableName,
    List<FFSQlColumn> columns,
  );

  // 新增列
  void addColumn({
    required String columnName,
    required FFSQlColumnType type,
  });

  // 实体转Map: 子类可以在这个方法剔除不要的字段
  Map<String, dynamic> entityToMap(FFSQlEntity entity);

  // Map 转 实体
  FFSQlEntity mapToEntity(Map<String, dynamic> dic);

  // 查询总数
  Future<int> getTableCount();

  // 插入
  Future<int> insert({
    required FFSQlEntity entity,
  });

  // 插入
  Future<int> insertByMap({
    required Map<String, dynamic> map,
  });

  // 批量插入
  Future<List<Object?>?> insertBatchByEntity({
    required List<FFSQlEntity> list,
    bool? ignoreError,
  });

  // 批量插入
  Future<List<Object?>?> insertBatchByMap({
    required List<Map<String, dynamic>> list,
    bool? ignoreError,
  });

  // 原始查询
  Future<List<Map<String, dynamic>>?> rawQuery(String sql, [List<Object?>? arguments]);

  // 查询
  Future<List<T>> query<T>({
    int? sqlid,
    int? limit,
    int? offset,
    String? where,
    String? orderby,
    List<dynamic>? whereArgs,
    Function(T e)? onReady,
  });

  // 查询 page从1开始
  Future<List<T>> query2<T>({
    required int page,
    int? sqlid,
    int? limit,
    String? where,
    String? orderby,
    List<dynamic>? whereArgs,
    Function(T e)? onReady,
  });

  // 查询 只取第一个
  Future<T?> queryOne<T>({
    int? sqlid,
    String? where,
    String? orderby,
    List<dynamic>? whereArgs,
    Function(T e)? onReady,
    bool isAdjust = true,
    bool isAssociate = false,
  });

  // 删除
  Future<bool> deleteBySqlid({int? sqlid});

  // 删除
  Future<bool> delete({
    int? sqlid,
    String? where,
    List<dynamic>? whereArgs,
  });

  // 批量删除
  Future<bool> deleteBatchBySqlId({
    required List<int> list,
  });

  // 更新
  Future<bool> updateByEntity({
    required int? sqlid,
    required FFSQlEntity entity,
  });

  // 更新
  Future<bool> updateByMap({
    required int? sqlid,
    required Map<String, dynamic> map,
  });

  // 批量更新
  Future<bool> updateBatchByEntity({
    required List<FFSQlEntity> list,
  });

  // 批量更新
  Future<bool> updateBatchByMap({
    required List<Map<String, dynamic>> list,
  });

  // 自定义批量操作
  @override
  Future<List<Object?>?> batchCustom({
    required Function(MyBatch myBatch) onCustom,
  });
}

class FFSQlEntity {
  int? sqlid;
  int? createTime;
  int? updateTime;

  FFSQlEntity({
    this.sqlid,
    this.createTime,
    this.updateTime,
  });

  FFSQlEntity.fromJson(Map<String, dynamic> json) {}

  Map<String, dynamic> toJson() {
    return {};
  }

  // 父类信息
  void superColumn(FFsql sql, Map<String, dynamic> map) {
    sqlid = globalSafeValueFromMap<int>(map, sql.getPrimaryKeyName()) ?? 0;
    createTime = globalSafeValueFromMap<int>(map, sql.getCreateTime()) ?? 0;
    updateTime = globalSafeValueFromMap<int>(map, sql.getUpdateTime()) ?? 0;
  }

  // 此时已经从表中获取到数据，如果你想改一下，就在这儿操作
  Future<void> adjustEntity() async {}

  // 关联查询
  Future<void> associateEntity() async {}
}

class FFSQlEntityDefault implements FFSQlEntity {
  @override
  int? createTime;

  @override
  int? sqlid;

  @override
  int? updateTime;

  @override
  void superColumn(FFsql sql, Map<String, dynamic> map) {
    sqlid = globalSafeValueFromMap<int>(map, sql.getPrimaryKeyName()) ?? 0;
    createTime = globalSafeValueFromMap<int>(map, sql.getCreateTime()) ?? 0;
    updateTime = globalSafeValueFromMap<int>(map, sql.getUpdateTime()) ?? 0;
  }

  @override
  Map<String, dynamic> toJson() {
    return {};
  }

  @override
  Future<void> adjustEntity() async {}

  @override
  Future<void> associateEntity() async {}
}

class FFSQlColumn {
  // 字段名
  String name;

  // 类型
  FFSQlColumnType? type;

  // 类型之后的信息
  String info;

  FFSQlColumn({
    required this.name,
    this.type = FFSQlColumnType.TEXT,
    this.info = "",
  });
}

// 字段类型
enum FFSQlColumnType {
  INTEGER,
  TEXT,
  REAL,
  BLOB,
  Custom,
}
